﻿using OpenAiMobile.Util.Extensions;
using OpenAiMobile.Util.Json;
using OpenAiMobile.Util.Services;

#if ANDROID
using OpenAiMobile.Platforms.Android;
#endif

namespace OpenAiMobile.Services
{
    public class StatisticsService : IStatisticsService
    {
        public event Action RegisterSuccess = () => { };

        public bool IsRegisterSuccess { get; private set; }

        public string OsVersion { get; private set; } //操作系统
        public string ComputerName { get; private set; } //计算机名称
        public string ComputerUserName { get; private set; } //用户名
        public bool Is64BitOperatingSystem { get; private set; } //64位操作系统
        public int ProcessorCount { get; private set; } //处理器核心个数
        public string CpuId { get; private set; } //CPU ID
        public string BoardId { get; private set; } //主板ID
        public string DiskId { get; private set; } //硬盘ID

        private Task _task;
        private CancellationTokenSource _tokenSource;

        private readonly ILogService _logService;
        private readonly IConfigService _configService;
        private readonly IHttpService _httpService;
        private readonly IPlatformService _platformService;

        public StatisticsService(
            ILogService logService,
            IConfigService configService,
            IHttpService httpService,
            IPlatformService platformService
        )
        {
            _logService = logService;
            _configService = configService;
            _httpService = httpService;
            _platformService = platformService;
        }

        public void Startup()
        {
            _tokenSource = new CancellationTokenSource();
            _task = Task.Run(async () => { await DoWorkAsync(_tokenSource.Token); });
        }

        public void Shutdown()
        {
            _tokenSource?.Cancel();
            _task?.Wait();
            _task?.Dispose();
            _task = null;
            _tokenSource?.Dispose();
            _tokenSource = null;
        }

        private async Task DoWorkAsync(CancellationToken token)
        {
            await GetStatisticsInfoAsync();

            while (true)
            {
                try
                {
                    if (token.IsCancellationRequested)
                    {
                        break;
                    }

                    var ret = await DoRegisterAsync(token);
                    if (ret && !token.IsCancellationRequested)
                    {
                        IsRegisterSuccess = true;
                        RegisterSuccess.Invoke();
                        break;
                    }

                    await Task.Delay(100, token);
                }
                catch (TaskCanceledException)
                {
                    break;
                }
            }
        }

        private async Task<bool> DoRegisterAsync(CancellationToken token)
        {
            try
            {
                if (string.IsNullOrEmpty(CpuId))
                {
                    CpuId = $"{Guid.NewGuid()}".Replace("-", "");
                }

                var phoneNumber = await _platformService.GetPhoneNumberAsync();
                if (string.IsNullOrEmpty(phoneNumber))
                {
                    phoneNumber = CpuId;
                }

                // ReSharper disable RedundantAnonymousTypePropertyName
                var dto = new
                {
                    CpuId = CpuId ?? string.Empty,
                    BoardId = phoneNumber,
                    DiskId = phoneNumber,
                    OsVersion = OsVersion ?? string.Empty,
                    ComputerName = ComputerName ?? string.Empty,
                    ComputerUserName = ComputerUserName ?? string.Empty,
                    Is64BitOperatingSystem = Is64BitOperatingSystem,
                    ProcessorCount = ProcessorCount
                };
                var body = JsonHelper.SerializeObject(dto);
                var url = $"{_configService.WebApiUrl}/api/statistics/register/pc";
                var ret = await _httpService.PostAsync(url, body, token);
                if (!ret.Item1)
                {
                    var message = $"注册用户信息失败：{ret.Item2}.";
                    _logService.Error(message);
                }
                else
                {
                    await _configService.SetAccountIdAsync(ret.Item2);
                }

                return ret.Item1;
            }
            catch (Exception e)
            {
                var message = $"注册用户信息异常：{e.GetFullMessage()}";
                _logService.Error(message);
                return false;
            }
        }

        private async Task GetStatisticsInfoAsync()
        {
            //sb.AppendLine($"Model: {DeviceInfo.Current.Model}");
            //sb.AppendLine($"Manufacturer: {DeviceInfo.Current.Manufacturer}");
            //sb.AppendLine($"Name: {DeviceInfo.Current.Name}");
            //sb.AppendLine($"OS Version: {DeviceInfo.Current.VersionString}");
            //sb.AppendLine($"Idiom: {DeviceInfo.Current.Idiom}");
            //sb.AppendLine($"Platform: {DeviceInfo.Current.Platform}");
            await Task.CompletedTask;
            try
            {
                ComputerName = DeviceInfo.Current.Manufacturer;
                ComputerUserName = DeviceInfo.Current.Name;
                OsVersion = DeviceInfo.Current.VersionString;
                Is64BitOperatingSystem = Environment.Is64BitOperatingSystem;
                ProcessorCount = Environment.ProcessorCount;
#if ANDROID
                CpuId = AndroidAppService.GetAndroidId();
#endif
                //DiskId = string.Join(',', ManagementInfrastructureHelper.GetDiskInfoList().Select(t => t.Model));
                // BoardId = ManagementInfrastructureHelper.GetBoardInfoList().FirstOrDefault()?.SerialNumber;
            }
            catch (Exception e)
            {
                _logService.Error($"获取统计信息失败：{e.GetFullMessage()}.");
            }

            //var info = await MachineInfo.RegisterAsync();
            //if (string.IsNullOrWhiteSpace(CpuId))
            //{
            //    CpuId = info.UUID;
            //}

            //if (string.IsNullOrWhiteSpace(DiskId))
            //{
            //    DiskId = info.UUID;
            //}

            //if (string.IsNullOrWhiteSpace(BoardId))
            //{
            //    BoardId = info.UUID;
            //}
        }
    }
}
